#pragma once

void *worker_threads(void *arg) 
{
	ThreadPool *threadPool = static_cast<ThreadPool *>(arg);
	threadPool->join(THREAD_TIMEOUT); // Time in ms between worker threads polling
	return NULL;
}

class Server
{

public:
	Server(unsigned long address)
	{
		// Server implementation 
		Reactor *itsReactor = Reactor::instance();
		// Test with all event services (Log, Patient and Alarm)
		threadPool = new ThreadPool(itsReactor);
		                                                 
		// Test with all event services (Log, Patient and Alarm)
		INET_Addr *logAddr = new INET_Addr(DEFAULT_PORT_LOG, address);
		Acceptor<LogEvent, SOCK_Acceptor> *logAcceptor = new Acceptor<LogEvent, SOCK_Acceptor>(itsReactor, logAddr, threadPool, false);
		LF_EventHandler *LFlogAcceptor = new LF_EventHandler(itsReactor, logAcceptor, threadPool, ACCEPT_EVENT);

		INET_Addr *patientAddr = new INET_Addr(DEFAULT_PORT_PATIENT, address);	
		Acceptor<PatientEvent, SOCK_Acceptor> *patientAcceptor = new Acceptor<PatientEvent, SOCK_Acceptor>(itsReactor, patientAddr, threadPool, false);
		LF_EventHandler *LFpatientAcceptor = new LF_EventHandler(itsReactor, patientAcceptor, threadPool, ACCEPT_EVENT);

		INET_Addr *alarmAddr = new INET_Addr(DEFAULT_PORT_ALARM, address);
		Acceptor<AlarmEvent, SOCK_Acceptor> *alarmAcceptor = new Acceptor<AlarmEvent, SOCK_Acceptor>(itsReactor, alarmAddr, threadPool, false);   
		LF_EventHandler *LFalarmAcceptor = new LF_EventHandler(itsReactor, alarmAcceptor, threadPool, ACCEPT_EVENT);
	}

	void run(void)
	{
		for (int i=0; i < MAX_THREADS-1; i++)
			Thread_Manager::instance()->spawn(worker_threads, threadPool);
		
		threadPool->join(THREAD_TIMEOUT);

		// Reactor without thread pool 
		// while (1) {
		//	 Reactor::instance()->handleEvents();
		// }
	}

private:
	ThreadPool *threadPool;
};
